package com.kaver.config;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.strategy.InlineShardingStrategyConfiguration;
import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.baomidou.dynamic.datasource.creator.DefaultDataSourceCreator;
import com.baomidou.dynamic.datasource.provider.AbstractDataSourceProvider;
import com.baomidou.dynamic.datasource.provider.DynamicDataSourceProvider;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;

@Configuration
public class DataSourceConfiguration{
	@Autowired
	DynamicDataSourceProperties properties;
	@Autowired
	private DefaultDataSourceCreator defaultDataSourceCreator;
	
	public DataSource getShardingDataSource(String dsName) throws SQLException {
		ShardingRuleConfiguration configuration = new ShardingRuleConfiguration();
		List<TableRuleConfiguration> tableRuleConfigs =  new ArrayList<TableRuleConfiguration>();
		TableRuleConfiguration ruleConfiguration = new TableRuleConfiguration("order_info", dsName + ".order_info_$->{0..1}");
		ruleConfiguration.setTableShardingStrategyConfig(new InlineShardingStrategyConfiguration("id", "order_info_$->{id % 2}"));
		tableRuleConfigs.add(ruleConfiguration);
		configuration.setTableRuleConfigs(tableRuleConfigs);
		Map<String, DataSource> dataSourceMap = new HashMap<String, DataSource>();
		dataSourceMap.put(dsName, defaultDataSourceCreator.createDataSource(properties.getDatasource().get(dsName)));
		return ShardingDataSourceFactory.createDataSource(dataSourceMap, configuration, new Properties());
	}

	@Bean
	public DynamicDataSourceProvider shardingDataSourceProvider() throws SQLException {
		Map<String, DataSourceProperty> datasourceMap = properties.getDatasource();
		Map<String, DataSource> shardingDataSourceMap = new HashMap<String, DataSource>();
		for (String dsName : datasourceMap.keySet()) {
			shardingDataSourceMap.put("sharding-"+ dsName, getShardingDataSource(dsName));
		}
		return new AbstractDataSourceProvider() {
			@Override
			public Map<String, DataSource> loadDataSources() {
				Map<String, DataSource> dataSourceMap = new HashMap<String, DataSource>();
				dataSourceMap.putAll(shardingDataSourceMap);
				return dataSourceMap;
			}
		};
	}
}
